package cn.seqdata.io;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Iterator;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

public class CsvReader<T> implements Iterable<T>, Closeable {
	private final BufferedReader reader;
	private final Function<String, T> function;
	private volatile String line = null;

	public CsvReader(Function<String, T> function, String fileName) throws IOException {
		this(function, fileName, "GBK");
	}

	public CsvReader(Function<String, T> function, String fileName, String charsetName) throws IOException {
		InputStream is = new FileInputStream(fileName);
		Reader in = new InputStreamReader(is, charsetName);
		this.reader = new BufferedReader(in);
		this.function = function;
	}

	@Override
	public Iterator<T> iterator() {
		return new Iterator<T>() {

			@Override
			public boolean hasNext() {
				try {
					line = reader.readLine();
					return Objects.nonNull(line);
				} catch (IOException ex) {
					return false;
				}
			}

			@Override
			public T next() {
				return function.apply(line);
			}
		};
	}

	public Stream<T> stream() {
		return StreamSupport.stream(spliterator(), false);
	}

	@Override
	public void close() throws IOException {
		reader.close();
	}
}
